define(['angular', 'jquery', 'lodash', 'd3'], function(angular, $, _) {
    'use strict';

    var app = angular.module('app', []);
    /*
    图谱过滤
    */
    app.filter('filterMap', function() {
        return function(name, data) {
            var root = {
                nodes: [],
                edges: []
            };
            var _obj = {},
                mainobj = {},
                cacheNum = {
                    'sub': {
                        name: '学科',
                        num: 0,
                        list: [],
                        color: '#f04848'
                    },
                    'aut': {
                        name: '作者',
                        num: 0,
                        list: [],
                        color: '#A37593'
                    },
                    'org': {
                        name: '机构',
                        num: 0,
                        list: [],
                        color: '#BD9BB1'
                    },
                    'kwd': {
                        name: '特征词',
                        num: 0,
                        list: [],
                        color: '#E0837B'
                    },
                    'jou': {
                        name: '期刊',
                        num: 0,
                        list: [],
                        color: '#e370f8'
                    },
                    'acp': {
                        name: '控制人',
                        num: 0,
                        list: [],
                        color: '#9675e8'
                    },
                    'shc': {
                        name: '参控股公司',
                        num: 0,
                        list: [],
                        color: '#f96cba'
                    },
                    'shp': {
                        name: '股东',
                        num: 0,
                        list: [],
                        color: '#24c1d8'
                    }
                };
            $(data).each(function(i, el) {
                $(el.graph).each(function(index, ele) {
                    var _nodes = ele.nodes,
                        _rship = ele.relationships;
                    for (var i = 0, l = _nodes.length; i < l; i++) {
                        if (!_obj[_nodes[i].id]) {
                            _nodes[i].type = _nodes[i].labels[0];
                            $.extend(_nodes[i], _nodes[i].properties); //拷贝子属性
                            delete _nodes[i].labels;
                            delete _nodes[i].properties;
                            if (_nodes[i].name === name) {
                                (_nodes[i].main = true);
                            }
                            root.nodes.push(_nodes[i]);
                            _obj[_nodes[i].id] = i + 1;
                            console.log('x', _nodes[i].type);
                            cacheNum[_nodes[i].type].num += 1;
                            if (name === _nodes[i].name) {
                                _nodes[i].open = true;
                                $.extend(true, mainobj, _nodes[i]);
                            }
                        }
                    }
                    for (var j = 0, lj = _rship.length; j < lj; j++) {
                        _rship[j].endNode == mainobj.id ? (_rship[j].arrow = 'in') : (_rship[j].arrow = 'out'); //箭头指向
                        root.edges.push(_rship[j]);
                    }
                });
            });
            root.edges.map(function(el, i) {
                el.source = _.findIndex(root.nodes, {
                    id: el.startNode
                });
                el.target = _.findIndex(root.nodes, {
                    id: el.endNode
                });
                el.targetType = root.nodes[el.target].type;
                el.targetMain = root.nodes[el.target].main;
            });
            return {
                cacheNum: cacheNum,
                mainobj: mainobj,
                root: root
            };
        };
    })

    app.directive('heatmapMax', function() {
            return {
                controller: function($rootScope, $scope, $http, $q, $filter, $timeout) {
                    var init = function(name, element, type) {
                        var deferred = $q.defer();
                        $http.get('/api/graph/ygra', {
                            params: {
                                c: name
                            }
                        }).success(function(data) {
                            if (data.code == 200) {
                                $scope.tiks = data.tik;
                            }
                            var fldata = $filter('filterMap')(name, data.results[0].data),
                                tiks = [];
                            console.log('fldata', fldata);

                            $('#heatmap-max').empty();
                            var root = fldata.root;
                            var ctn = $(element);
                            var width = ctn.width() - 60;
                            var height = 700;
                            var img_w = 20;
                            var img_h = 20;
                            var cacheNum = fldata.cacheNum;
                            var mainobj = fldata.mainobj;
                            var svg = d3.select('#heatmap-max')
                                .append("svg")
                                .attr('id', 'heatmaps')
                                .attr("width", width)
                                .attr("height", height)
                                .append('g')
                                .attr('class', 'g-center');
                            svg.call(d3.behavior.zoom()).on('dblclick.zoom', null);

                            var _this = this;
                            var refx = 32,
                                refy = 0,
                                refcx = 40,
                                refcy = 0;
                            for (var item in cacheNum) {
                                svg.append("svg:defs").selectAll("marker")
                                    .data(["end"])
                                    .enter().append("svg:marker")
                                    .attr("id", "arrowline" + item)
                                    .attr("viewBox", "0 -5 10 10")
                                    .attr("refX", refx)
                                    .attr("refY", refy)
                                    .style('fill', cacheNum[item].color)
                                    .attr("markerWidth", 6)
                                    .attr("markerHeight", 6)
                                    .attr("orient", "auto")
                                    .append("svg:path")
                                    .attr("d", "M0,-5L10,0L0,5"); // 插入箭头
                                svg.append("svg:defs").selectAll("marker")
                                    .data(["end"])
                                    .enter().append("svg:marker")
                                    .attr("id", "arrowline" + item + 'pos')
                                    .attr("viewBox", "0 -5 10 10")
                                    .attr("refX", refcx)
                                    .attr("refY", refcy)
                                    .style('fill', cacheNum[item].color)
                                    .attr("markerWidth", 6)
                                    .attr("markerHeight", 6)
                                    .attr("orient", "auto")
                                    .append("svg:path")
                                    .attr("d", "M0,-5L10,0L0,5");
                            }
                            var nodes = [],
                                links = [];
                            var force = d3.layout.force()
                                .nodes(nodes)
                                .links(links)
                                .size([width, height])
                                .linkDistance(function(d) {
                                    var length,
                                        Type,
                                        ratio = (type == 'middle' ? 0.9 : 1),
                                        name = d.target.name,
                                        obj = (name === mainobj.name ? d.source : d.target),
                                        Type = obj.type;
                                    switch (Type) {
                                        case 'sub':
                                            length = 220;
                                            break;
                                        case 'aut':
                                            length = 270;
                                            break;
                                        case 'org':
                                            length = 320;
                                            break;
                                        case 'ind':
                                            length = 370;
                                            break;
                                        default:
                                            length = 150;
                                            break;
                                    }
                                    return length * ratio;
                                })
                                .charge(-300)
                                .on("tick", tick);
                            var node = svg.selectAll(".node"),
                                link = svg.selectAll(".link"),
                                linktext = svg.selectAll(".lineText");

                            function tick() {
                                root.nodes.forEach(function(d) {
                                    d.x = d.x - img_w / 2 < 0 ? img_w / 2 : d.x;
                                    d.x = d.x + img_w / 2 > width ? width - img_w / 2 : d.x;
                                    d.y = d.y - img_h / 2 < 0 ? img_h / 2 : d.y;
                                    d.y = d.y + img_h / 2 + 20 > height ? height - img_h / 2 - 20 : d.y;
                                });
                                link.attr("d", function(d) {
                                    var dx = d.target.x - d.source.x,
                                        dy = d.target.y - d.source.y,
                                        dr = Math.sqrt(dx * dx + dy * dy),
                                        line;
                                    if (d.poly) {
                                        line = "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
                                    } else {
                                        line = "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
                                    }
                                    return line;
                                });
                                //更新结文字
                                node.attr("transform", function(d) {
                                    return "translate(" + d.x + "," + d.y + ")";
                                });
                            }
                            var drag = force.drag()
                                .on("dragstart", function(d) {
                                    d.fixed = true;
                                })
                                .on("dragend", function() {})
                                .on("drag", function() {})
                            var update = function() {
                                link = link.data(force.links());
                                link.enter()
                                    .append("path")
                                    .attr('class', function(d) {
                                        return $.isEmptyObject(d.properties) ? 'link-die' : 'link';
                                    })
                                    .attr('id', function(d) {
                                        return d.endNode + d.startNode;
                                    })
                                    .style('stroke', function(d) {
                                        return $.isEmptyObject(d.properties) ? '#ddd' : cacheNum[d.targetType].color;
                                    })
                                    .attr("marker-end", function(d) {
                                        var arrow;
                                        arrow = "url(#arrowline" + d.targetType + (d.targetMain ? "pos" : "") + ")";
                                        return arrow;
                                    })
                                linktext = linktext.data(force.links());
                                linktext.enter().append("text")
                                    .append("textPath")
                                    .attr("xlink:href", function(d) {
                                        return "#" + d.endNode + d.startNode;
                                    })
                                    .attr('fill', function(d) {
                                        return cacheNum[d.targetType].color;
                                    })
                                    .attr('class', 'linetext')
                                    .style("text-anchor", "middle")
                                    .attr("startOffset", "50%")
                                    .attr("cursor", "pointer")
                                    .text(function(d) {
                                        return d.type;
                                    }).on('click', function(d) {
                                        lineClick(d)
                                    });
                                link.exit().remove();
                                node = node.data(force.nodes());
                                node.enter()
                                    .append('g')
                                    .on('mouseover', function() {
                                        d3.select(this).select('circle').style('stroke', '#c7ebfc');
                                    }).on('mouseout', function() {
                                        d3.select(this).select('circle').style('stroke', 'transparent');
                                    }).call(drag);

                                node.append("circle")
                                    .attr("class", "node")
                                    .style('fill', function(d) {
                                        var color = cacheNum[d.type].color;
                                        return color;
                                    })
                                    .attr("r", function(d) {
                                        var r = 30;
                                        d.main && (r = 36);
                                        return r;
                                    }).on("click", function(d) {
                                        d.fixed = true;
                                        nodeclick(d)
                                    }).on("mouseenter", function(d) {
                                        hoverTips(d, 'mouseover');
                                    }).on("mouseleave", function(d) {
                                        hoverTips(d, 'mouseout');
                                    });
                                node.append("text")
                                    .attr("class", "nodetext")
                                    .attr("dy", ".55em")
                                    .attr("text-anchor", "middle")
                                    .attr('font-size', function() {
                                        return '12px';
                                    })
                                    .text(function(d) {
                                        var name = d.name;
                                        if (name.length > 4) {
                                            name = name.substring(0, 4)
                                        }
                                        return name;
                                    }).on("click", function(d) {
                                        nodeclick(d)
                                    }).on("mouseenter", function(d) {
                                        hoverTips(d, 'mouseover');
                                    }).on("mouseleave", function(d) {
                                        hoverTips(d, 'mouseout');
                                    });
                                node.order(); //node 重排
                                force.start();
                            }

                            function start() {
                                for (var i = 0, l = root.nodes.length; i < l; i++) {
                                    nodes.push(root.nodes[i])
                                }
                                for (var j = 0, lg = root.edges.length; j < lg; j++) {
                                    links.push(root.edges[j]);
                                }
                                update();
                            }

                            start();

                            function hoverTips(d, type) {
                                var el = d3.event,
                                    left = el.layerX + 20,
                                    top = el.layerY + 15,
                                    tplHtml = ['<ul class="hnode-hover-tips" style="left:' + left + 'px;top:' + top + 'px">',
                                        '      <li>' + d.name + '</li>',
                                        '</ul>',
                                    ].join(""),
                                    tpl;
                                if (type == 'mouseover') {
                                    tpl = $(tplHtml).appendTo('#heatmap-max');
                                } else if (type == 'mouseout') {
                                    $('.hnode-hover-tips').remove();
                                }
                                el.stopImmediatePropagation();
                            }

                            function nodeclick(d) {
                                $('.hnode-menu').remove();
                                var el = d3.event,
                                    left = el.layerX,
                                    top = el.layerY,
                                    tplHtml = ['<ul class="hnode-menu" style="left:' + left + 'px;top:' + top + 'px">',
                                        '      <li>查看子节点</li>',
                                        '</ul>',
                                    ].join(""),
                                    tpl = $(tplHtml).appendTo('#heatmap-max');

                                if (!d.main) {
                                    el.stopImmediatePropagation();
                                    tpl.find('li:eq(0)').on('click', function() {
                                        nodeDbclick(d);
                                    })
                                }
                            }
                            $('body').on('click', function() {
                                $('.hnode-menu').remove();
                            })

                            function nodeDbclick(d) {
                                d.fixed = false;
                                if (d.open) {
                                    return;
                                }
                                $http.get('/api/graph/ncgra', {
                                    params: {
                                        nc: d.id,
                                        nf: mainobj.id,
                                    }
                                }).success(function(res) {
                                    var data = $filter('filterMap')(name, res.results[0].data).root;

                                    console.log('data', data);
                                    for (var i = 0, l = data.nodes.length; i < l; i++) {
                                        if (_.findIndex(nodes, {
                                                id: data.nodes[i].id
                                            }) < 0) {
                                            nodes.push(data.nodes[i])
                                        }
                                    }
                                    for (var j = 0, lg = data.edges.length; j < lg; j++) {
                                        links.push(data.edges[j]);
                                    }
                                    links.map(function(el) {
                                        el.source = _.findIndex(nodes, {
                                            id: el.startNode
                                        });
                                        el.target = _.findIndex(nodes, {
                                            id: el.endNode
                                        });
                                        el.targetType = nodes[el.target].type;
                                        el.targetMain = nodes[el.target].main;
                                    })
                                    update()
                                    d.open = true;
                                })
                            }

                            /*点击连线发送请求*/
                            function lineClick(d) {
                                console.log(d.targetType)
                                var targetType = d.targetType;
                                if (targetType == 'kwd' || targetType == 'jou') {
                                    var params = {
                                        type: (d.targetType == 'kwd') ? '0' : '1',
                                        s_name: d.source.name,
                                        t_name: d.target.name,
                                    }
                                    $http.get('/med/subject/papers', {
                                        params: params
                                    }).success(function(data) {
                                        var mes = data.message;
                                        var papers = mes.papers;
                                        console.log('papers', papers);
                                        if ($('.tip')[0]) {
                                            $('.tip').remove();
                                        }
                                        var aTr = [];
                                        papers.forEach(function(n) {
                                            var sLi = ["<li><a href=" + n.url + " target='_blank' title=" + n.title + '>' + n.title + "</a></li>"].join("");
                                            aTr.push(sLi);
                                        });
                                        console.log('aTr', aTr);

                                        //
                                        var sTip = ["<div class=\"tip\">",
                                            "            <div class=\"title\">",
                                            // "                <span class=\"text\">学科 -> 特征词（影响力：10.21）</span>",
                                            "                <span class=\"text\">" + d.type + "</span>",
                                            "                <span class=\"icon-close\"></span>",
                                            "            </div>",
                                            "            <div class=\"title-bar\">",
                                            "                期刊标题：",
                                            "            </div>",
                                            "            <ul>" + aTr.join('') + "</ul>",
                                            "</div>"
                                        ].join("");

                                        $('#heatmap-max').append(sTip);

                                        //隐藏tip
                                        $('.tip .icon-close').click(function() {
                                            $('.tip').remove();
                                        });
                                        console.log('d》》》', params)
                                    })
                                }

                            }
                        });
                    }

                    init('基础医学', '#heatmap-max', 'middle');
                }
            }
        })
        //
});
